package repository

import (
	"fitness/go-admin/internal/model"
	"fitness/go-admin/pkg/cache"
	"fmt"
	"time"

	"gorm.io/gorm"
)

type CourseRepository interface {
	Create(course *model.Course) error
	Update(course *model.Course) error
	Delete(id uint) error
	GetByID(id uint) (*model.Course, error)
	List(page, pageSize int) ([]model.Course, int64, error)
}

type courseRepository struct {
	db *gorm.DB
}

func NewCourseRepository(db *gorm.DB) CourseRepository {
	return &courseRepository{db: db}
}

func (r *courseRepository) Create(course *model.Course) error {
	if err := r.db.Create(course).Error; err != nil {
		return err
	}

	// 清除列表缓存
	cache.DeletePattern("course:list:*")

	return nil
}

func (r *courseRepository) Update(course *model.Course) error {
	if err := r.db.Save(course).Error; err != nil {
		return err
	}

	// 清除相关缓存
	cache.DeleteCache(fmt.Sprintf("course:id:%d", course.ID))
	cache.DeletePattern("course:list:*")

	return nil
}

func (r *courseRepository) Delete(id uint) error {
	if err := r.db.Delete(&model.Course{}, id).Error; err != nil {
		return err
	}

	// 清除相关缓存
	cache.DeleteCache(fmt.Sprintf("course:id:%d", id))
	cache.DeletePattern("course:list:*")

	return nil
}

// GetByID - 热点数据缓存
func (r *courseRepository) GetByID(id uint) (*model.Course, error) {
	// 1. 尝试从缓存获取
	cacheKey := fmt.Sprintf("course:id:%d", id)
	var course model.Course

	if err := cache.GetJSON(cacheKey, &course); err == nil {
		return &course, nil // 缓存命中
	}

	// 2. 缓存未命中，查询数据库
	if err := r.db.First(&course, id).Error; err != nil {
		return nil, err
	}

	// 3. 写入缓存（5分钟过期）
	_ = cache.SetJSON(cacheKey, course, 5*time.Minute)

	return &course, nil
}

// List - 列表数据缓存
func (r *courseRepository) List(page, pageSize int) ([]model.Course, int64, error) {
	// 1. 尝试从缓存获取
	cacheKey := fmt.Sprintf("course:list:%d:%d", page, pageSize)

	type CachedResult struct {
		Courses []model.Course `json:"courses"`
		Total   int64          `json:"total"`
	}

	var cached CachedResult
	if err := cache.GetJSON(cacheKey, &cached); err == nil {
		return cached.Courses, cached.Total, nil // 缓存命中
	}

	// 2. 缓存未命中，查询数据库
	var courses []model.Course
	var total int64

	offset := (page - 1) * pageSize

	if err := r.db.Model(&model.Course{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	err := r.db.Offset(offset).Limit(pageSize).Order("start_time DESC").Find(&courses).Error

	if err != nil {
		return nil, 0, err
	}

	// 3. 写入缓存（2分钟过期，列表数据变化较快）
	cached = CachedResult{
		Courses: courses,
		Total:   total,
	}
	_ = cache.SetJSON(cacheKey, cached, 2*time.Minute)

	return courses, total, err
}
